package com.glela.goods.service.impl;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.glela.cache.model.RedisKey;
import com.glela.cache.redis.RedisUtil;
import com.glela.goods.dao.InventoryDao;
import com.glela.goods.dao.vo.LimitSaleGoodsInventroy;
import com.glela.goods.mapper.InventoryMapper;
import com.glela.goods.model.Inventory;
import com.glela.goods.model.LimitTimeSaleDetail;
import com.glela.goods.model.vo.inventory.DynamicInventoryVo;
import com.glela.goods.service.InventoryService;
import com.glela.goods.service.LimitTimeSaleDetailService;

import cn.jpush.api.utils.StringUtils;

/**
 * @author liujie
 * @2016年10月20日
 */
@Service("inventoryService")
public class InventoryServiceImpl implements InventoryService {
	private static Logger				logger	= LoggerFactory.getLogger(InventoryServiceImpl.class);
	@Autowired
	private InventoryDao				inventoryDao;
	@Autowired
	private LimitTimeSaleDetailService	limitTimeSaleDetailService;
	@Autowired
	private InventoryMapper				inventoryMapper;

	@Autowired
	RedisUtil redisUtil;

	@Override
	public Inventory selectInventoryByGoodsStoreIdSpecInfo(long goodsId, int storeId, String specInfo) {
		return inventoryDao.selectInventoryByGoodsStoreIdSpecInfo(goodsId, storeId, specInfo);
	}

	@Override
	public Inventory findByProductId(long productId) {
		return inventoryDao.selectInventoryByProductId(productId);
	}

	@Override
	public long findDynaByGoodsId(long goodsId) {
		//查询所有库存
		List<Inventory> checkInventoryList = inventoryDao.selectByGoodsId(goodsId, 1);
		if (CollectionUtils.isEmpty(checkInventoryList)) {
			return 0;
		}
		//查询当前分时抢购商品信息
		List<LimitTimeSaleDetail> _limit_time_sale_detail_list = limitTimeSaleDetailService.queryByGoodsId(goodsId, new Date());
		Map<Long, LimitTimeSaleDetail> check_limit_detail = new HashMap<Long, LimitTimeSaleDetail>();
		if (CollectionUtils.isNotEmpty(_limit_time_sale_detail_list)) {
			for (LimitTimeSaleDetail limitTimeSaleDetail : _limit_time_sale_detail_list) {
				check_limit_detail.put(limitTimeSaleDetail.getSkuNo(), limitTimeSaleDetail);
			}
		}

		long inventory_total_num = 0;//总库存
		for (Inventory _check_inventory : checkInventoryList) {
			LimitTimeSaleDetail _check_limit_sale_detail = check_limit_detail.get(_check_inventory.getProductId());
			if (_check_limit_sale_detail == null) {//无分时抢购
				inventory_total_num += _check_inventory.getInventoryNum();
			} else {//有分时抢购,比较真是库存与分时抢购限购数，去最小值
				if (_check_limit_sale_detail.getSkuCount() < 0) {
					_check_limit_sale_detail.setSkuCount(0);
				}
				inventory_total_num += _check_limit_sale_detail.getSkuCount() < _check_inventory.getInventoryNum() ? _check_limit_sale_detail.getSkuCount() : _check_inventory.getInventoryNum();
			}
		}
		return inventory_total_num;
	}

	@Override
	public Map<Long, Long> findDynaByGoodsId(Collection<Long> goodsIds) {
		Map<Long, Long> rstMap = new HashMap<>();
		//商品库存明细
		Map<Long, Set<Inventory>> checkInventoryGoodsMap = inventoryDao.selectByGoodsIds(goodsIds, 1);
		if (MapUtils.isEmpty(checkInventoryGoodsMap)) {
			return rstMap;
		}
		//商品分时抢购明细
		Map<Long, Map<Long, LimitTimeSaleDetail>> limitSaleDetailMap = limitTimeSaleDetailService.queryByGoodsIds(goodsIds, new Date());
		//封装商品库存总和
		for (Long goodsId : checkInventoryGoodsMap.keySet()) {
			long inventoryNum = 0;
			Set<Inventory> set = checkInventoryGoodsMap.get(goodsId);
			if (CollectionUtils.isEmpty(set)) {
				continue;
			}
			for (Inventory inventory : set) {
				if (inventory == null) {
					continue;
				}
				LimitTimeSaleDetail _limitTimeSaleDetail = null;
				if (MapUtils.isNotEmpty(limitSaleDetailMap.get(goodsId))) {
					_limitTimeSaleDetail = limitSaleDetailMap.get(goodsId).get(inventory.getProductId());
				}
				if (_limitTimeSaleDetail == null) {
					inventoryNum += inventory.getInventoryNum();
				} else {
					Long limitCount = _limitTimeSaleDetail.getSkuCount()>_limitTimeSaleDetail.getShowCount()?_limitTimeSaleDetail.getShowCount():_limitTimeSaleDetail.getSkuCount();
					inventoryNum += limitCount.intValue() < inventory.getInventoryNum() ? limitCount : inventory.getInventoryNum();
				}
			}
			rstMap.put(goodsId, inventoryNum);
		}
		return rstMap;
	}

	@Override
	public long findDynaByGoodsId(long goodsId, int limitTimeSaleId) {
		return inventoryDao.selectLimitSaleInventoryByGoodsId(limitTimeSaleId, goodsId);
	}

	/** 查询实际库存，再查当前分时抢购限购数，取最小值返回 */
	@Override
	public DynamicInventoryVo findDynaByProductId(long productId) {
		DynamicInventoryVo dynamicInventoryVo = new DynamicInventoryVo();
		//		Product _check_product = this.productMapper.selectProductById(productId);
		//		if (_check_product == null) {
		//			return dynamicInventoryVo;
		//		}
		Inventory _iInventory = this.inventoryDao.selectInventoryByProductId(productId);
		if (_iInventory == null) {
			logger.error("货品{}没有库存记录", productId);
			return dynamicInventoryVo;
		}
		if (_iInventory.getStatus() == 0) {
			logger.error("货品{}库存记录{}不可用", productId, _iInventory.getId());
			return dynamicInventoryVo;
		}
		LimitTimeSaleDetail checkTimeSaleDetail = limitTimeSaleDetailService.queryByProductId(productId, new Date());
		if (checkTimeSaleDetail == null) {
			dynamicInventoryVo.setInventoryId(_iInventory.getId());
			dynamicInventoryVo.setInventoryNumAvl(_iInventory.getInventoryNum());
		} else {
			if (checkTimeSaleDetail.getIsDelete() == 1) {
				return dynamicInventoryVo;
			}
			if (checkTimeSaleDetail.getSkuCount() < 0) {
				checkTimeSaleDetail.setSkuCount(0);
			}
			dynamicInventoryVo.setInventoryId(_iInventory.getId());
			dynamicInventoryVo.setInventoryNumAvl(checkTimeSaleDetail.getSkuCount().intValue() < _iInventory.getInventoryNum() ? checkTimeSaleDetail.getSkuCount() : _iInventory.getInventoryNum());
		}
		return dynamicInventoryVo;
	}

	@Override
	public LimitSaleGoodsInventroy findDynaByGoodsId(Map<Integer, Set<Long>> limitSaleGoodsIdMap) {
		return inventoryDao.selectLimitSaleInventoryByGoodsId(limitSaleGoodsIdMap);
	}

	public void addInventory(Inventory inventory) throws Exception {

		//同一个PRODUCTID，在库存表中只有一条记录, 

		if (inventory.getProductId() < 1) {
			throw new RuntimeException("添加库存时发生错误! 产品货号(productid)为空");
		}

		if (inventory.getGoodId() < 1) {
			throw new RuntimeException("添加库存时发生错误! 产品货号(goodsid)为空");
		}

		Inventory queryInventory = inventoryMapper.selectInventoryByPid(inventory.getProductId());

		if (queryInventory != null) {
			throw new RuntimeException("缓存对象时发生错误! 该货号已经有库存记录,不能重复添加");
		}

		Long _id = inventoryMapper.insertSelective(inventory);

		Inventory _inventory = inventoryMapper.selectByPrimaryKey(_id);//这次查询可以不查MYSQL，直接存储，防止该表中默认值字段在直接缓存的时候没有缓存进去，所以进行一次主键查询
		String inventoryRedisCacheKey = RedisKey.INVENTORY_KEY_HASH + _id;
		String ret = redisUtil.hmset(inventoryRedisCacheKey, _inventory);
		if (StringUtils.isEmpty(ret)) {
			throw new RuntimeException("缓存对象时发生错误! 添加失败");
		}
	}

	@Override
	public int updateInventory(Long inventoryId, Integer quantity) throws Exception {
		int updateCount = inventoryMapper.updateLocalInventory(inventoryId, quantity);
		Inventory inventory = inventoryMapper.selectByPrimaryKey(inventoryId);
		String inventoryRedisCacheKey = RedisKey.INVENTORY_KEY_HASH + inventoryId;
		//每次重新缓存对象，达到更新的目的，也可以只更新HASH中库存字段
		//		org.apache.commons.beanutils.BeanUtils SD;
		logger.error("准备缓存库存...................");
		String ret = redisUtil.hmset(inventoryRedisCacheKey, inventory);
		if (StringUtils.isEmpty(ret)) {
			throw new RuntimeException("缓存对象时发生错误! 更新失败");
		}
		return updateCount;
	}

}
